#include "StdAfx.h"
#include "cermgr.h"
#include "EasyCrypt.h"
#include "encryptfile.h"
#include "common.h"
#include <string>
using namespace std;

std::string CCerMgr::GetSerialCode()
{
	std::string SerialCode;
	SerialCode.append(m_szMachineCode);
	SerialCode+=m_mod_Client;
	SerialCode+=m_pubkey_Client;
	SerialCode+=m_prikey_Client;
	SerialCode+=m_mod_Service;
	SerialCode+=m_pubkey_Service;
	SerialCode+= m_communication_Key;
	return SerialCode;
}

//解析规则XML数据流
bool CCerMgr::Parse(const char *msg, list<PROCINFO> &PloyItem)
{
	TiXmlDocument doc;
	doc.Parse(msg);
	
	if (doc.Error())
	{
		TRACE("Error in %s: %s\n", doc.Value(), doc.ErrorDesc() );
		return false;
	}
	TiXmlElement *rule = doc.RootElement()->FirstChildElement();
	TiXmlElement *ProcessRole = rule->FirstChildElement();
	TiXmlElement *ProcItem;
	for(ProcItem = ProcessRole->FirstChildElement();
		ProcItem;
		ProcItem = ProcItem->NextSiblingElement())
	{
		PROCINFO item;
		memset(&item, 0, sizeof(item));
		strcpy(item.szProcName, ProcItem->Attribute("name"));
		TiXmlElement  *Filter = ProcItem->FirstChildElement();
		if(Filter)
		{
			C2W(item.szExtentName, EXTEN_LENGTH, Filter->GetText());
		}
		PloyItem.push_back(item);
	}
	return true;
}

//解析证书
bool CCerMgr::ParseCer(LPCSTR pszFilePath,const  char *szMachineCode)
{	CEncryptFile file;	std::string str;	if(!file.LoadFile(pszFilePath,str,szMachineCode))
	{
		return false;
	}
	
	//解析证书
	
	TiXmlDocument doc;
	doc.Parse(str.c_str());

	if (doc.Error())
	{
		TRACE("Error in %s: %s\n", doc.Value(), doc.ErrorDesc() );
		return false;
	}
	TiXmlElement *info = doc.RootElement()->FirstChildElement();
	{
		TiXmlElement *clientinfo = info->FirstChildElement();
		ASSERT(clientinfo);
		m_szMachineCode.assign(clientinfo->Attribute("HardWareNum"));

		{
			TiXmlElement *ModClient = clientinfo->FirstChildElement();
			ASSERT(ModClient);
			m_mod_Client.assign(ModClient->GetText());

			TiXmlElement *PubkeyClient = ModClient->NextSiblingElement();
			ASSERT(PubkeyClient);
			m_pubkey_Client.assign(PubkeyClient->GetText());

			TiXmlElement *PrikeyClient = PubkeyClient->NextSiblingElement();
			ASSERT(PrikeyClient);
			m_prikey_Client.assign(PrikeyClient->GetText());
		}
		TiXmlElement *servinfo = clientinfo->NextSiblingElement();
		ASSERT(servinfo);
		{
			TiXmlElement *ModServ = servinfo->FirstChildElement();
			ASSERT(ModServ);
			m_mod_Service.assign(ModServ->GetText());

			TiXmlElement *PubkeyServ = ModServ->NextSiblingElement();
			ASSERT(PubkeyServ);
			m_pubkey_Service.assign(PubkeyServ->GetText());
		}

		TiXmlElement *CommunicationKey = servinfo->NextSiblingElement(); 
		ASSERT(CommunicationKey);
		m_communication_Key.assign(CommunicationKey->GetText());

		TiXmlElement *Signtext = CommunicationKey->NextSiblingElement(); 
		ASSERT(Signtext);
		m_Hashtext.assign(Signtext->GetText());
		m_Hashtext.append(" ");
	}

	//验证签名
	if (!ec::RSA::Sign_verify(m_Hashtext, GetSerialCode(), m_mod_Service, m_pubkey_Service))
	{
		//签名验证失败文件已被修改
		return false;
	}
	return true;
}

bool CCerMgr::ParsePak(LPCSTR pszFilePath, const  char *szMachineCode, OfflineData *ptrOffData)
{
	CEncryptFile file;	std::string PakData;	if(!file.LoadFile(pszFilePath, PakData, szMachineCode))
	{
		return false;
	}
	TiXmlDocument doc;
	doc.Parse(PakData.c_str());

	if (doc.Error())
	{
		TRACE("Error in %s: %s\n", doc.Value(), doc.ErrorDesc() );
		return false;
	}
	
	TiXmlElement *Config = doc.RootElement();
	TiXmlElement *MC = Config->FirstChildElement("MC");
	assert(MC);
	ptrOffData->strMecCode.assign(MC->GetText());

	TiXmlElement *ServInfo = MC->NextSiblingElement();
	{
		TiXmlElement *IP= ServInfo->FirstChildElement();
		assert(IP);
		ptrOffData->strIp.assign(IP->GetText());
		TiXmlElement *Port = IP->NextSiblingElement();
		assert(Port);
		ptrOffData->struPort.assign(Port->GetText());
	}
	
	TiXmlElement *Ploy = ServInfo->NextSiblingElement();
	{
		TiXmlElement *Rule= Ploy->FirstChildElement();
		assert(Rule);
		ptrOffData->strCryptRule.assign(Rule->GetText());
		TiXmlElement *Key = Rule->NextSiblingElement();
		assert(Key);
		ptrOffData->strCryptKey.assign(Key->GetText());
	}
	TiXmlElement *TimeEnd = Ploy->NextSiblingElement();
	assert(TimeEnd);
	ptrOffData->strEndTime.assign(TimeEnd->GetText());
	
	return true;
}